home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl
-
- use strict;
- use Getopt::Long;
-
- $ENV{'PATH'} = '/Developer/Tools:' . $ENV{'PATH'};
-
- my $result;
- my $usage = "usage: $0 <file1> <file2>\n";
- my $rezHack = "/..namedfork/rsrc";
- my $headerPrinted;
- my $indent = " ";
- my $skipPartialFiles;
-
- GetOptions('P' => \$skipPartialFiles);
-
- my $file1 = shift @ARGV;
- my $file2 = shift @ARGV;
-
- unless($file1 && $file2) {
- print $usage;
- exit(1);
- }
-
- if(-l $file1 || -l $file2) {
- my $result = compareSymlinks($file1, $file2);
- exit($result);
- }
-
- die "$file1 does not exist" unless -e $file1;
- die "$file2 does not exist" unless -e $file2;
-
- if (-d $file1 || -d $file2) {
- my $result = compareDirectories($file1, $file2);
- exit($result);
- }
-
- ########### Metadata
-
- my $m1 = "/tmp/macdiff.1." . $$;
- my $m2 = "/tmp/macdiff.2." . $$;
-
- my $metadata1 = readMetadata($file1);
- my $metadata2 = readMetadata($file2);
-
- if($skipPartialFiles) {
- foreach($metadata1, $metadata2) {
- if(/type: "iGpf"/ && /creator: "iGet"/) {
- print STDERR "$0: Skipping partial file comparison\n";
- exit 0;
- }
- }
- }
-
- writeMetadata($metadata1, $m1);
- writeMetadata($metadata2, $m2);
-
- my $metadataDifferences = `diff --suppress-common-lines -y -W 70 $m1 $m2`;
- unlink $m1, $m2;
-
- if($metadataDifferences) {
- printHeader();
- print STDERR "Metadata differences:\n";
- my @lines = split("\n", $metadataDifferences);
- print STDERR $indent, join("\n" . $indent, @lines), "\n";
- $result = 1;
- }
-
- ########### Data fork
-
- compareFiles($file1, $file2, "Data fork", 1) || { $result = 1 };
-
- ########### Resource fork
-
- compareFiles($file1 . $rezHack, $file2 . $rezHack, "Resource fork") || { $result = 1 };
-
- $headerPrinted && printBar();
-
- exit $result;
-
- ########### Subroutines
-
- sub readMetadata {
-
- my ($inputFile, $tmpFile) = @_;
-
- my $metadataCommand = "GetFileInfo " . quotemeta($inputFile) . " | tail +2";
- my $metadata = `$metadataCommand`;
- $? && die("GetFileInfo returned error");
-
- return $metadata;
- }
-
- sub writeMetadata {
- my ($data, $file) = @_;
- open TMP, ">$file";
- print TMP $data;
- close TMP;
- }
-
- sub compareFiles {
- my ($localFile1, $localFile2, $title, $compareMode) = @_;
-
- my @differences;
- my ($f1mode, $f1length) = (stat($localFile1))[2,7];
- my ($f2mode, $f2length) = (stat($localFile2))[2,7];
-
- if ($f1length != $f2length) {
- push @differences, "lengths ($f1length, $f2length)";
- }
-
- system("cmp", "-s", $localFile1, $localFile2);
- my $cmpResult = ($? >> 8);
-
- if($cmpResult) {
- push @differences, "contents";
- }
-
- if($compareMode && ($f1mode != $f2mode)) {
- push @differences, "perms ($f1mode, $f2mode)";
- }
-
- if(@differences) {
- printHeader();
- print STDERR $title, " diffs: ", join(", ", @differences), "\n";
- return 0;
- }
-
- return 1;
- }
-
- sub printHeader {
- $headerPrinted && return;
-
- printBar();
- print STDERR "macdiff found differences between the following items:\n";
- print STDERR $indent, $file1, "\n";
- print STDERR $indent, $file2, "\n";
- $headerPrinted = 1;
- }
-
- sub printBar {
- print STDERR "***************************************************************************\n";
- }
-
- sub compareSymlinks {
- my ($file1, $file2) = @_;
-
- if((-l $file1) != (-l $file2)) {
- printHeader();
- print STDERR "one is a symlink and the other isn't\n";
- printBar();
- return 1;
- }
-
- my $dest1 = readlink($file1);
- my $dest2 = readlink($file2);
- if($dest1 ne $dest2) {
- printHeader();
- print ETDERR "symlink targets don't match:\n";
- print $indent, "$file1 -> $dest1\n", $indent, "$file2 -> $dest2\n";
- printBar();
- return 1;
- }
- return 0;
- }
-
- sub compareDirectories {
- my ($dir1, $dir2) = @_;
-
- if((-d $dir1) != (-d $dir2)) {
- printHeader();
- print STDERR "one is a folder and the other isn't\n";
- printBar();
- return 1;
- }
-
- my ($f1mode, $f1date) = (stat($dir1))[2,9];
- my ($f2mode, $f2date) = (stat($dir2))[2,9];
-
- my @differences;
- if($f1mode != $f2mode) {
- push @differences, "perms ($f1mode, $f2mode)";
- }
-
- if($f1date != $f2date) {
- push @differences, "mod date ($f1date, $f2date)";
- }
-
- if(@differences) {
- printHeader();
- print STDERR "differences: ", join(", ", @differences), "\n";
- return 1;
- }
-
- return 0;
- }
-